﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CodeDynamiksEngine;
using MESCodeFile;

namespace mes_tublay
{
    public partial class frmConfig : Form
    {
        //Configuration attributes
        CodeProcessor proc = new CodeProcessor();
        string selKey = "";                     //Currently selected key.
        string[] keylist;                       //Array list of saved keys.

        //Form Constructor
        public frmConfig()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }
        //Form initialization
        private void InitializeForm()
        {
            //Register GUI events
            DoEvents();
            //Register processor execution events.
            CodeProcessorExe();
            
            //Initialize the CodeProcessor by pre-defining a LF Unit
            CodeScript s = new CodeScript("INIT");
            s.Add(CodeIns.LFU_NEW_CORE);
            proc.Run(s);

        }
        //GUI Events
        void DoEvents()
        {
            //Raised when the user double clicks the key listbox
            lstKey.DoubleClick += new EventHandler(delegate
            {
                //Store the selected key name
                selKey = keylist[lstKey.SelectedIndex];
                //Read the value of the selected key from the configuration and display it on the textbox.
                txtValue.Text = Common.CFG.Read(selKey).ToString();

                //Perform GUI automation
                grpValue.Enabled = true;
                grpKey.Enabled = false;
                lstKey.Enabled = false;
                grpImportExport.Enabled = false;
            });
            lstKey.Click += new EventHandler(delegate
            {
                if (lstKey.SelectedIndex != -1)
                    btnRemove.Enabled = true;
                else
                    btnRemove.Enabled = true;
            });

            //Raised when the user clicks the Accept button
            btnAccept.Click += new EventHandler(delegate
            {
                //Read the new value of the settings from the textbox and update the master configuration cache.
                Common.CFG.Edit(selKey, txtValue.Text);
                //Reset the textbox
                txtValue.Text = "";
                //Update the key list.
                ShowKeys();
                
                //Perform GUI automation.
                grpValue.Enabled = false;
                grpKey.Enabled = true;
                lstKey.Enabled = true;
                grpImportExport.Enabled = true;
            });
            //Raised when the user clicks the Cancel button.
            btnCancel.Click += new EventHandler(delegate
            {
                txtValue.Text = "";

                grpValue.Enabled = false;
                grpKey.Enabled = true;
                lstKey.Enabled = true;
                grpImportExport.Enabled = true;
            });
            //Raised when the user clicks the Add New Key button
            btnKey.Click += new EventHandler(delegate
            {
                //Warn the user about the adding of new key.
                DialogResult confirmAddKey = MessageBox.Show("This will add a new key.\r\nDo you wish to continue?",
                    "Add Key", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
                //If the user confirms the action add the key to the master configuration cache.
                if (confirmAddKey == DialogResult.Yes)
                {
                    Common.CFG.Add(txtKey.Text, "");
                    txtKey.Text = "";
                    //Update the key list
                    ShowKeys();
                }
            });
            btnRemove.Click += new EventHandler(delegate
            {
                //Warn the user about the adding of new key.
                DialogResult confirmAddKey = MessageBox.Show("This will remove an existing key.\r\nDo you wish to continue?",
                    "Add Key", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
                //If the user confirms the action removes the from to the master configuration cache.
                if (confirmAddKey == DialogResult.Yes)
                {
                    Common.CFG.Delete(Common.CFG.GetKeyList()[lstKey.SelectedIndex]);
                    //Update the key list
                    ShowKeys();
                }
            });
            //Raised when the user Clicks the Save and Apply button
            btnSave.Click += new EventHandler(delegate
            {
                //Create a CodeScript object for saving the configuration cache
                CodeScript s = new CodeScript("SAVE");
                s.Add(CodeIns.SYS_USE_CORE, 0);
                s.Add(CodeIns.LFU_CONFIG_WRITE, "mes_tublay", Common.CFG);
                s.Add(CodeIns.LFU_END);
                proc.Run(s);
            });
            //Raised when the user clicks the Export button
            btnExport.Click += new EventHandler(delegate
            {
                //Instantiate a SaveFileDialog object for exporting configuration file.
                SaveFileDialog savedlg = new SaveFileDialog();
                //Set the SaveFileDialog properties.
                savedlg.OverwritePrompt = true;
                savedlg.Title = "Export configuration";
                savedlg.Filter = "Configuration File|*.cfg|All Files|*.*";
                savedlg.AddExtension = true;
                savedlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                //If the user clicks ok,
                if (savedlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    //Do GUI automation
                    lstKey.Enabled = false;
                    grpKey.Enabled = false;
                    grpValue.Enabled = false;
                    grpImportExport.Enabled = false;

                    //Create a CodeScript for exporting configuration.
                    CodeScript s = new CodeScript("EXPORT");
                    s.Add(CodeIns.SYS_USE_CORE, 0);
                    s.Add(CodeIns.LFU_CONFIG_EXPORT, Common.CFG, savedlg.FileName);
                    s.Add(CodeIns.LFU_END);
                    proc.Run(s);
                }
            });
            //Raised when the user clicks the Import button.
            btnImport.Click += new EventHandler(delegate
            {
                //Instantiate an OpenFileDialog object for importing configuration file.
                OpenFileDialog opendlg = new OpenFileDialog();
                //Set the OpenFileDialog properties
                opendlg.Filter = "Configuration file|*.cfg|All Files|*.*";
                opendlg.CheckFileExists = true;
                opendlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                opendlg.Title = "Import Configuration";
                //If the user clicks Ok,
                if (opendlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    //Do GUI automation
                    lstKey.Enabled = false;
                    grpKey.Enabled = false;
                    grpValue.Enabled = false;
                    grpImportExport.Enabled = false;

                    //Create a CodeScript for importing the configuration file.
                    CodeScript s = new CodeScript("IMPORT");
                    s.Add(CodeIns.SYS_USE_CORE, 0);
                    s.Add(CodeIns.LFU_CONFIG_IMPORT, opendlg.FileName);
                    s.Add(CodeIns.LFU_END);
                    proc.Run(s);
                }
            });
        }
        //CodeProcessor Events
        void CodeProcessorExe()
        {
            //If CodeProcessor has completed the execution
            proc.ProcessCompleted += new EventHandler(delegate
            {
                //Make sure that operation happens on the main thread.
                proc.SafeCall(this, delegate
                {
                    //Check if the process name is EXPORT or IMPORT and do necessary GUI automations.
                    if (proc.GetLastProcessName() == "EXPORT" || proc.GetLastProcessName() == "IMPORT")
                    {
                        lstKey.Enabled = true;
                        grpKey.Enabled = true;
                        grpValue.Enabled = false;
                        grpImportExport.Enabled = true;
                    }
                    //Check for CodeProcessor errors, if there are, show via MessageBox.
                    if (proc.State == ProcessorFlag.DataRdyErr ||
                        proc.State == ProcessorFlag.Error ||
                        proc.State == ProcessorFlag.ReadyErr)
                    {
                        MessageBox.Show(proc.GetLastProcessName() + ":" + proc.GetProcessorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        proc.ClearErrorFlag();
                        return;
                    }
                    //If the CodeProcessor is good to go, check the LastProcess name/
                    switch (proc.GetLastProcessName())
                    {
                        //When saving successfuly, show a message to the user.
                        case "SAVE":
                            MessageBox.Show("Save successful", "Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            break;
                        //When importing and reading configuration successfuly,
                        case "IMPORT":
                        case "READ":
                            //Fetch the output
                            DataCache dc;
                            proc.DataFetch(out dc);
                            //Store the read/imported configuration to master configuration cache.
                            Common.CFG = dc.ExportConfig(0);
                            //Display the new settings
                            ShowKeys();
                            //Apply the settings to the application.
                            ApplySettings();
                            break;
                        //Initialize successful, load the application settings.
                        case "INIT":
                            LoadSettings();
                            break;
                    }
                });
            });
        }
        //Load the application settings
        public void LoadSettings()
        {
            //Create a CodeScript for reading configuration.
            CodeScript s = new CodeScript("READ");
            s.Add(CodeIns.SYS_USE_CORE, 0);
            //The name of the folder is 'mes_tublay', and the config file is 'settings'
            s.Add(CodeIns.LFU_CONFIG_READ, "mes_tublay", "settings");
            s.Add(CodeIns.LFU_END);
            proc.Run(s);
        }
        //Display the keys and values on the listbox.
        void ShowKeys()
        {
            //Clear the listbox.
            lstKey.Items.Clear();
            //Obtain the list of keys and its values
            keylist = Common.CFG.GetKeyList();
            //Separate the key from value so that it can be display on a single-column listbox.
            object[] vals = Common.CFG.ReadAll();
            object[] ls = new object[keylist.Length];
            //Iterate thru the keys and values.
            for (int i = 0; i < ls.Length; i++)
            {
                ls[i] = keylist[i] + "=" + vals[i];
            }
            //Display everythin on the listbox.
            lstKey.Items.AddRange(ls);
        }
        //Apply the application settings.
        void ApplySettings()
        {
            try
            {
                //Apply the screen mode
                bool fs = bool.Parse(Common.CFG.Read("FULLSCREEN").ToString());
                if (fs == true)
                    Common.PARENT.WindowState = FormWindowState.Maximized;
                else
                    Common.PARENT.WindowState = FormWindowState.Normal;
                Common.PARENT.Refresh();

                //Other settings to apply goes here...
                //Initialize the live notification.
                Common.PARENT.InitializeLiveNotification();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Settings", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
